#pragma once
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <csignal>
#include <cstdlib>
#include <cstdint>
#include <iomanip>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <memory>
#include <thread>
#include <shared_mutex>
#include <mutex>
#include <ctime>
#include <locale>
#include <future>
#include <string.h>
#include <iostream>
#include <sstream>
#include <codecvt>
#include <condition_variable>
#include <atomic>
#include <functional>
#include <jemalloc/jemalloc.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#include <fcntl.h>
#include <sys/epoll.h>
#include <netinet/tcp.h>
#include <cassert>
#include <filesystem>
#include <system_error>
#include <openssl/sha.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <boost/stacktrace.hpp>
#include <boost/asio.hpp>
#include <fmt/core.h>
#include "cgzStruct.h"
#include "cgzCireBuffer.h"

#define cgz_this_error(sfmt, ...) this->getPool()->errLog(__FILE__, __FUNCTION__, __LINE__, fmt::format(sfmt, __VA_ARGS__).c_str())
#define cgz_that_error(sfmt, ...) that->getPool()->errLog(__FILE__, __FUNCTION__, __LINE__, fmt::format(sfmt, __VA_ARGS__).c_str())

void intiCore();
void lookMems();

extern long diffsec;
long fnowsec(); // 秒
long fnowmls(); // 毫秒
long fnowmcs(); // 微秒
long fdifsec(long sec); // 偏移

std::string cxx_trace();
std::string get_current_date();

void reverseBytes(const char *src, char *tar, uint8_t size);
bool containsChinese(const std::string &str);
std::wstring utf8ToWstring(const std::string &str);
std::string wstringToUtf8(const std::wstring &wstr);
std::string base64_encode(const unsigned char *buffer, size_t length);
std::string websocket_generate_acceptkey(const std::string &key);
std::string websocket_check_handshake(std::string &request);
std::string websocket_generate_handkey();
std::string websocket_generate_handshake(std::string &key, std::string &ip, int port);
bool websocket_validate_handshake(const std::string &response, const std::string &key);

class cgzCWDecode;
bool webscoket_encode_message(const char *data, int len, int t, bool use_mask, char **output, int &outlen, const char *reason = nullptr);
bool webscoket_decode_message(cgzCireBuffer &cire, cgzCWDecode &de);

#define READLEN (1024 * 1024)
#define ONESEND 1460
#define SENDLEN (ONESEND * 1024)
#define MASK_LENGTH 4
// 帧状态
enum WEBSOCKET_DECODE_STATE
{
    WEBSOCKET_D_NONE,        // 无状态
    WEBSOCKET_D_FIN,         // FIN
    WEBSOCKET_D_RSV1,        // RSV1
    WEBSOCKET_D_RSV2,        // RSV2
    WEBSOCKET_D_RSV3,        // RSV3
    WEBSOCKET_D_OPCODE,      // 操作码
    WEBSOCKET_D_PAYLOAD_LEN, // 负载长度
    WEBSOCKET_D_MASK,        // 掩码
    WEBSOCKET_D_MASKING_KEY, // 掩码密钥
    WEBSOCKET_D_PAYLOAD,     // 负载
    WEBSOCKET_D_END,         // 结束
};

enum WEBSCOKET_SEND_ENUM
{
    WEBSOCKET_SEND_NONE,   // 无状态
    WEBSOCKET_SEND_HAND,   // 握手
    WEBSOCKET_SEND_TEXT,   // 文本
    WEBSOCKET_SEND_BINARY, // 二进制
    WEBSOCKET_SEND_PING,   // 心跳
    WEBSOCKET_SEND_PONG,   // 响应心跳
    WEBSOCKET_SEND_DISC,   // 关闭连接
};

class cgzCWDecode
{
public:
    cgzCWDecode();
    virtual ~cgzCWDecode();

public:
    WEBSOCKET_DECODE_STATE fs;
    uint8_t fin;
    uint8_t rsv1;
    uint8_t rsv2;
    uint8_t rsv3;
    uint8_t opcode;
    uint8_t mask;
    uint8_t payload_length;
    uint8_t masking_key[4];

public:
    int decode_len;            // 解码长度
    char decode_data[READLEN]; // 数据缓存
    WEBSCOKET_SEND_ENUM rt;    // 接收类型
};

const unsigned char close_normal[] = {0x03, 0xe8};     // 正常关闭
const unsigned char close_server[] = {0x03, 0xe9};     // 服务器关闭
const unsigned char close_protocol[] = {0x03, 0xea};   // 协议错误
const unsigned char close_datatype[] = {0x03, 0xeb};   // 收到不支持的数据类型
const unsigned char close_reserved[] = {0x03, 0xec};   // 保留状态码
const unsigned char close_nocode[] = {0x03, 0xed};     // 没有状态码（保留）
const unsigned char close_connect[] = {0x03, 0xee};    // 连接异常关闭（保留）
const unsigned char close_inconsist[] = {0x03, 0xef};  // 收到不一致的数据
const unsigned char close_policy[] = {0x03, 0xf0};     // 违反政策
const unsigned char close_auth[] = {0x03, 0xf1};       // 认证失败
const unsigned char close_unknown[] = {0x03, 0xf2};    // 未知错误
const unsigned char close_reserved1[] = {0x03, 0xf3};  // 保留状态码
const unsigned char close_reserved2[] = {0x03, 0xf4};  // 保留状态码
const unsigned char close_reserved3[] = {0x03, 0xf5};  // 保留状态码
const unsigned char close_reserved4[] = {0x03, 0xf6};  // 保留状态码
const unsigned char close_reserved5[] = {0x03, 0xf7};  // 保留状态码
const unsigned char close_reserved6[] = {0x03, 0xf8};  // 保留状态码
const unsigned char close_reserved7[] = {0x03, 0xf9};  // 保留状态码
const unsigned char close_reserved8[] = {0x03, 0xfa};  // 保留状态码
const unsigned char close_reserved9[] = {0x03, 0xfb};  // 保留状态码
const unsigned char close_reserved10[] = {0x03, 0xfc}; // 保留状态码
const unsigned char close_reserved11[] = {0x03, 0xfd}; // 保留状态码
const unsigned char close_reserved12[] = {0x03, 0xfe}; // 保留状态码
const unsigned char close_reserved13[] = {0x03, 0xff}; // 保留状态码
